<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
        "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link href="../Styles/sure3.css" rel="stylesheet" type="text/css"/>
    <link href="../Styles/base1.css" rel="stylesheet" type="text/css"/>
</head>

<body>
<div class="markdown-body entry-content" itemprop="text">
    <h1><a href="#数组的扩展"  class="anchor" id="user-content-数组的扩展">

    </a>数组的扩展
    </h1>
    <h2><a href="#扩展运算符"  class="anchor" id="user-content-扩展运算符">

    </a>扩展运算符
    </h2>
    <h3><a href="#含义"  class="anchor" id="user-content-含义">

    </a>含义
    </h3>
    <p>扩展运算符（spread）是三个点（<code>...</code>）。它好比 rest 参数的逆运算，将一个数组转为用逗号分隔的参数序列。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-en">console</span>.<span
            class="pl-c1">log</span>(<span class="pl-k">...</span>[<span class="pl-c1">1</span>, <span
            class="pl-c1">2</span>, <span class="pl-c1">3</span>])
<span class="pl-c"><span class="pl-c">//</span> 1 2 3</span>

<span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-c1">1</span>, <span
                class="pl-k">...</span>[<span class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span class="pl-c1">4</span>], <span
                class="pl-c1">5</span>)
<span class="pl-c"><span class="pl-c">//</span> 1 2 3 4 5</span>

[<span class="pl-k">...</span><span class="pl-c1">document</span>.<span class="pl-c1">querySelectorAll</span>(<span
                class="pl-s"><span class="pl-pds">'</span>div<span class="pl-pds">'</span></span>)]
<span class="pl-c"><span class="pl-c">//</span> [&lt;div&gt;, &lt;div&gt;, &lt;div&gt;]</span></pre>
    </div>
    <p>该运算符主要用于函数调用。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span
            class="pl-en">push</span>(<span class="pl-smi">array</span>, <span class="pl-k">...</span><span
            class="pl-v">items</span>) {
  <span class="pl-smi">array</span>.<span class="pl-c1">push</span>(<span class="pl-k">...</span>items);
}

<span class="pl-k">function</span> <span class="pl-en">add</span>(<span class="pl-smi">x</span>, <span
                class="pl-smi">y</span>) {
  <span class="pl-k">return</span> x <span class="pl-k">+</span> y;
}

<span class="pl-k">const</span> <span class="pl-c1">numbers</span> <span class="pl-k">=</span> [<span
                class="pl-c1">4</span>, <span class="pl-c1">38</span>];
<span class="pl-en">add</span>(<span class="pl-k">...</span>numbers) <span class="pl-c"><span class="pl-c">//</span> 42</span></pre>
    </div>
    <p>上面代码中，<code>array.push(...items)</code>和<code>add(...numbers)</code>这两行，都是函数的调用，它们的都使用了扩展运算符。该运算符将一个数组，变为参数序列。
    </p>
    <p>扩展运算符与正常的函数参数可以结合使用，非常灵活。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span
            class="pl-en">f</span>(<span class="pl-smi">v</span>, <span class="pl-smi">w</span>, <span
            class="pl-smi">x</span>, <span class="pl-smi">y</span>, <span class="pl-smi">z</span>) { }
<span class="pl-k">const</span> <span class="pl-c1">args</span> <span class="pl-k">=</span> [<span
                class="pl-c1">0</span>, <span class="pl-c1">1</span>];
<span class="pl-en">f</span>(<span class="pl-k">-</span><span class="pl-c1">1</span>, <span class="pl-k">...</span>args, <span
                class="pl-c1">2</span>, <span class="pl-k">...</span>[<span class="pl-c1">3</span>]);</pre>
    </div>
    <p>扩展运算符后面还可以放置表达式。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">arr</span> <span
            class="pl-k">=</span> [
  <span class="pl-k">...</span>(x <span class="pl-k">&gt;</span> <span class="pl-c1">0</span> <span
                class="pl-k">?</span> [<span class="pl-s"><span class="pl-pds">'</span>a<span
                class="pl-pds">'</span></span>] <span class="pl-k">:</span> []),
  <span class="pl-s"><span class="pl-pds">'</span>b<span class="pl-pds">'</span></span>,
];</pre>
    </div>
    <p>如果扩展运算符后面是一个空数组，则不产生任何效果。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-k">...</span>[], <span class="pl-c1">1</span>]
<span class="pl-c"><span class="pl-c">//</span> [1]</span></pre>
    </div>
    <h3><a href="#替代数组的-apply-方法"  class="anchor" id="user-content-替代数组的-apply-方法">

    </a>替代数组的 apply 方法
    </h3>
    <p>由于扩展运算符可以展开数组，所以不再需要<code>apply</code>方法，将数组转为函数的参数了。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> ES5 的写法</span>
<span class="pl-k">function</span> <span class="pl-en">f</span>(<span class="pl-smi">x</span>, <span
                class="pl-smi">y</span>, <span class="pl-smi">z</span>) {
  <span class="pl-c"><span class="pl-c">//</span> ...</span>
}
<span class="pl-k">var</span> args <span class="pl-k">=</span> [<span class="pl-c1">0</span>, <span
                class="pl-c1">1</span>, <span class="pl-c1">2</span>];
<span class="pl-smi">f</span>.<span class="pl-c1">apply</span>(<span class="pl-c1">null</span>, args);

<span class="pl-c"><span class="pl-c">//</span> ES6的写法</span>
<span class="pl-k">function</span> <span class="pl-en">f</span>(<span class="pl-smi">x</span>, <span
                class="pl-smi">y</span>, <span class="pl-smi">z</span>) {
  <span class="pl-c"><span class="pl-c">//</span> ...</span>
}
<span class="pl-k">let</span> args <span class="pl-k">=</span> [<span class="pl-c1">0</span>, <span
                class="pl-c1">1</span>, <span class="pl-c1">2</span>];
<span class="pl-en">f</span>(<span class="pl-k">...</span>args);</pre>
    </div>
    <p>下面是扩展运算符取代<code>apply</code>方法的一个实际的例子，应用<code>Math.max</code>方法，简化求出一个数组最大元素的写法。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> ES5 的写法</span>
<span class="pl-c1">Math</span>.<span class="pl-smi">max</span>.<span class="pl-c1">apply</span>(<span class="pl-c1">null</span>, [<span
                class="pl-c1">14</span>, <span class="pl-c1">3</span>, <span class="pl-c1">77</span>])

<span class="pl-c"><span class="pl-c">//</span> ES6 的写法</span>
<span class="pl-c1">Math</span>.<span class="pl-c1">max</span>(<span class="pl-k">...</span>[<span
                class="pl-c1">14</span>, <span class="pl-c1">3</span>, <span class="pl-c1">77</span>])

<span class="pl-c"><span class="pl-c">//</span> 等同于</span>
<span class="pl-c1">Math</span>.<span class="pl-c1">max</span>(<span class="pl-c1">14</span>, <span
                class="pl-c1">3</span>, <span class="pl-c1">77</span>);</pre>
    </div>
    <p>上面代码中，由于 JavaScript
        不提供求数组最大元素的函数，所以只能套用<code>Math.max</code>函数，将数组转为一个参数序列，然后求最大值。有了扩展运算符以后，就可以直接用<code>Math.max</code>了。</p>
    <p>另一个例子是通过<code>push</code>函数，将一个数组添加到另一个数组的尾部。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> ES5的 写法</span>
<span class="pl-k">var</span> arr1 <span class="pl-k">=</span> [<span class="pl-c1">0</span>, <span
                class="pl-c1">1</span>, <span class="pl-c1">2</span>];
<span class="pl-k">var</span> arr2 <span class="pl-k">=</span> [<span class="pl-c1">3</span>, <span
                class="pl-c1">4</span>, <span class="pl-c1">5</span>];
<span class="pl-c1">Array</span>.<span class="pl-c1">prototype</span>.<span class="pl-smi">push</span>.<span
                class="pl-c1">apply</span>(arr1, arr2);

<span class="pl-c"><span class="pl-c">//</span> ES6 的写法</span>
<span class="pl-k">let</span> arr1 <span class="pl-k">=</span> [<span class="pl-c1">0</span>, <span
                class="pl-c1">1</span>, <span class="pl-c1">2</span>];
<span class="pl-k">let</span> arr2 <span class="pl-k">=</span> [<span class="pl-c1">3</span>, <span
                class="pl-c1">4</span>, <span class="pl-c1">5</span>];
<span class="pl-smi">arr1</span>.<span class="pl-c1">push</span>(<span class="pl-k">...</span>arr2);</pre>
    </div>
    <p>上面代码的 ES5
        写法中，<code>push</code>方法的参数不能是数组，所以只好通过<code>apply</code>方法变通使用<code>push</code>方法。有了扩展运算符，就可以直接将数组传入<code>push</code>方法。
    </p>
    <p>下面是另外一个例子。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> ES5</span>
<span class="pl-k">new</span> (<span class="pl-c1">Date</span>.<span class="pl-smi">bind</span>.<span class="pl-c1">apply</span>(<span
                class="pl-c1">Date</span>, [<span class="pl-c1">null</span>, <span class="pl-c1">2015</span>, <span
                class="pl-c1">1</span>, <span class="pl-c1">1</span>]))
<span class="pl-c"><span class="pl-c">//</span> ES6</span>
<span class="pl-k">new</span> <span class="pl-en">Date</span>(<span class="pl-k">...</span>[<span
                class="pl-c1">2015</span>, <span class="pl-c1">1</span>, <span class="pl-c1">1</span>]);</pre>
    </div>
    <h3><a href="#扩展运算符的应用"  class="anchor" id="user-content-扩展运算符的应用">

    </a>扩展运算符的应用
    </h3>
    <p><strong>（1）复制数组</strong></p>
    <p>数组是复合的数据类型，直接复制的话，只是复制了指向底层数据结构的指针，而不是克隆一个全新的数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">a1</span> <span
            class="pl-k">=</span> [<span class="pl-c1">1</span>, <span class="pl-c1">2</span>];
<span class="pl-k">const</span> <span class="pl-c1">a2</span> <span class="pl-k">=</span> a1;

a2[<span class="pl-c1">0</span>] <span class="pl-k">=</span> <span class="pl-c1">2</span>;
a1 <span class="pl-c"><span class="pl-c">//</span> [2, 2]</span></pre>
    </div>
    <p>上面代码中，<code>a2</code>并不是<code>a1</code>的克隆，而是指向同一份数据的另一个指针。修改<code>a2</code>，会直接导致<code>a1</code>的变化。</p>
    <p>ES5 只能用变通方法来复制数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">a1</span> <span
            class="pl-k">=</span> [<span class="pl-c1">1</span>, <span class="pl-c1">2</span>];
<span class="pl-k">const</span> <span class="pl-c1">a2</span> <span class="pl-k">=</span> <span class="pl-smi">a1</span>.<span
                class="pl-c1">concat</span>();

a2[<span class="pl-c1">0</span>] <span class="pl-k">=</span> <span class="pl-c1">2</span>;
a1 <span class="pl-c"><span class="pl-c">//</span> [1, 2]</span></pre>
    </div>
    <p>上面代码中，<code>a1</code>会返回原数组的克隆，再修改<code>a2</code>就不会对<code>a1</code>产生影响。</p>
    <p>扩展运算符提供了复制数组的简便写法。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">a1</span> <span
            class="pl-k">=</span> [<span class="pl-c1">1</span>, <span class="pl-c1">2</span>];
<span class="pl-c"><span class="pl-c">//</span> 写法一</span>
<span class="pl-k">const</span> <span class="pl-c1">a2</span> <span class="pl-k">=</span> [<span class="pl-k">...</span>a1];
<span class="pl-c"><span class="pl-c">//</span> 写法二</span>
<span class="pl-k">const</span> [<span class="pl-k">...</span><span class="pl-c1">a2</span>] <span class="pl-k">=</span> a1;</pre>
    </div>
    <p>上面的两种写法，<code>a2</code>都是<code>a1</code>的克隆。</p>
    <p><strong>（2）合并数组</strong></p>
    <p>扩展运算符提供了数组合并的新写法。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> ES5</span>
[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>].<span class="pl-c1">concat</span>(more)
<span class="pl-c"><span class="pl-c">//</span> ES6</span>
[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-k">...</span>more]

<span class="pl-k">var</span> arr1 <span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>a<span
                class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>b<span
                class="pl-pds">'</span></span>];
<span class="pl-k">var</span> arr2 <span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>c<span
                class="pl-pds">'</span></span>];
<span class="pl-k">var</span> arr3 <span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>d<span
                class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>e<span
                class="pl-pds">'</span></span>];

<span class="pl-c"><span class="pl-c">//</span> ES5的合并数组</span>
<span class="pl-smi">arr1</span>.<span class="pl-c1">concat</span>(arr2, arr3);
<span class="pl-c"><span class="pl-c">//</span> [ 'a', 'b', 'c', 'd', 'e' ]</span>

<span class="pl-c"><span class="pl-c">//</span> ES6的合并数组</span>
[<span class="pl-k">...</span>arr1, <span class="pl-k">...</span>arr2, <span class="pl-k">...</span>arr3]
<span class="pl-c"><span class="pl-c">//</span> [ 'a', 'b', 'c', 'd', 'e' ]</span></pre>
    </div>
    <p><strong>（3）与解构赋值结合</strong></p>
    <p>扩展运算符可以与解构赋值结合起来，用于生成数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> ES5</span>
a <span class="pl-k">=</span> list[<span class="pl-c1">0</span>], rest <span class="pl-k">=</span> <span class="pl-smi">list</span>.<span
                class="pl-c1">slice</span>(<span class="pl-c1">1</span>)
<span class="pl-c"><span class="pl-c">//</span> ES6</span>
[a, <span class="pl-k">...</span>rest] <span class="pl-k">=</span> list</pre>
    </div>
    <p>下面是另外一些例子。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> [<span
            class="pl-c1">first</span>, <span class="pl-k">...</span><span class="pl-c1">rest</span>] <span
            class="pl-k">=</span> [<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span
            class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span class="pl-c1">5</span>];
first <span class="pl-c"><span class="pl-c">//</span> 1</span>
rest  <span class="pl-c"><span class="pl-c">//</span> [2, 3, 4, 5]</span>

<span class="pl-k">const</span> [<span class="pl-c1">first</span>, <span class="pl-k">...</span><span
                class="pl-c1">rest</span>] <span class="pl-k">=</span> [];
first <span class="pl-c"><span class="pl-c">//</span> undefined</span>
rest  <span class="pl-c"><span class="pl-c">//</span> []</span>

<span class="pl-k">const</span> [<span class="pl-c1">first</span>, <span class="pl-k">...</span><span
                class="pl-c1">rest</span>] <span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">"</span>foo<span
                class="pl-pds">"</span></span>];
first  <span class="pl-c"><span class="pl-c">//</span> "foo"</span>
rest   <span class="pl-c"><span class="pl-c">//</span> []</span></pre>
    </div>
    <p>如果将扩展运算符用于数组赋值，只能放在参数的最后一位，否则会报错。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> [<span class="pl-k">...</span><span
            class="pl-c1">butLast</span>, <span class="pl-c1">last</span>] <span class="pl-k">=</span> [<span
            class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span
            class="pl-c1">4</span>, <span class="pl-c1">5</span>];
<span class="pl-c"><span class="pl-c">//</span> 报错</span>

<span class="pl-k">const</span> [<span class="pl-c1">first</span>, <span class="pl-k">...</span><span class="pl-c1">middle</span>, <span
                class="pl-c1">last</span>] <span class="pl-k">=</span> [<span class="pl-c1">1</span>, <span
                class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span class="pl-c1">5</span>];
<span class="pl-c"><span class="pl-c">//</span> 报错</span></pre>
    </div>
    <p><strong>（4）字符串</strong></p>
    <p>扩展运算符还可以将字符串转为真正的数组。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-k">...</span><span class="pl-s"><span
            class="pl-pds">'</span>hello<span class="pl-pds">'</span></span>]
<span class="pl-c"><span class="pl-c">//</span> [ "h", "e", "l", "l", "o" ]</span></pre>
    </div>
    <p>上面的写法，有一个重要的好处，那就是能够正确识别四个字节的 Unicode 字符。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-s"><span class="pl-pds">'</span>x<span
            class="pl-cce">\uD83D\uDE80</span>y<span class="pl-pds">'</span></span>.<span
            class="pl-c1">length</span> <span class="pl-c"><span class="pl-c">//</span> 4</span>
[<span class="pl-k">...</span><span class="pl-s"><span class="pl-pds">'</span>x<span class="pl-cce">\uD83D\uDE80</span>y<span
                class="pl-pds">'</span></span>].<span class="pl-c1">length</span> <span class="pl-c"><span class="pl-c">//</span> 3</span></pre>
    </div>
    <p>上面代码的第一种写法，JavaScript 会将四个字节的 Unicode 字符，识别为 2 个字符，采用扩展运算符就没有这个问题。因此，正确返回字符串长度的函数，可以像下面这样写。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">length</span>(<span
            class="pl-smi">str</span>) {
  <span class="pl-k">return</span> [<span class="pl-k">...</span>str].<span class="pl-c1">length</span>;
}

<span class="pl-en">length</span>(<span class="pl-s"><span class="pl-pds">'</span>x<span
                class="pl-cce">\uD83D\uDE80</span>y<span class="pl-pds">'</span></span>) <span class="pl-c"><span
                class="pl-c">//</span> 3</span></pre>
    </div>
    <p>凡是涉及到操作四个字节的 Unicode 字符的函数，都有这个问题。因此，最好都用扩展运算符改写。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> str <span class="pl-k">=</span> <span
            class="pl-s"><span class="pl-pds">'</span>x<span class="pl-cce">\uD83D\uDE80</span>y<span
            class="pl-pds">'</span></span>;

<span class="pl-smi">str</span>.<span class="pl-c1">split</span>(<span class="pl-s"><span class="pl-pds">'</span><span
                class="pl-pds">'</span></span>).<span class="pl-c1">reverse</span>().<span
                class="pl-c1">join</span>(<span class="pl-s"><span class="pl-pds">'</span><span class="pl-pds">'</span></span>)
<span class="pl-c"><span class="pl-c">//</span> 'y\uDE80\uD83Dx'</span>

[<span class="pl-k">...</span>str].<span class="pl-c1">reverse</span>().<span class="pl-c1">join</span>(<span
                class="pl-s"><span class="pl-pds">'</span><span class="pl-pds">'</span></span>)
<span class="pl-c"><span class="pl-c">//</span> 'y\uD83D\uDE80x'</span></pre>
    </div>
    <p>上面代码中，如果不用扩展运算符，字符串的<code>reverse</code>操作就不正确。</p>
    <p><strong>（5）实现了 Iterator 接口的对象</strong></p>
    <p>任何 Iterator 接口的对象（参阅 Iterator 一章），都可以用扩展运算符转为真正的数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> nodeList <span
            class="pl-k">=</span> <span class="pl-c1">document</span>.<span class="pl-c1">querySelectorAll</span>(<span
            class="pl-s"><span class="pl-pds">'</span>div<span class="pl-pds">'</span></span>);
<span class="pl-k">let</span> array <span class="pl-k">=</span> [<span class="pl-k">...</span>nodeList];</pre>
    </div>
    <p>
        上面代码中，<code>querySelectorAll</code>方法返回的是一个<code>nodeList</code>对象。它不是数组，而是一个类似数组的对象。这时，扩展运算符可以将其转为真正的数组，原因就在于<code>NodeList</code>对象实现了
        Iterator 。</p>
    <p>对于那些没有部署 Iterator 接口的类似数组的对象，扩展运算符就无法将其转为真正的数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> arrayLike <span class="pl-k">=</span> {
  <span class="pl-s"><span class="pl-pds">'</span>0<span class="pl-pds">'</span></span><span class="pl-k">:</span> <span
                class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>,
  <span class="pl-s"><span class="pl-pds">'</span>1<span class="pl-pds">'</span></span><span class="pl-k">:</span> <span
                class="pl-s"><span class="pl-pds">'</span>b<span class="pl-pds">'</span></span>,
  <span class="pl-s"><span class="pl-pds">'</span>2<span class="pl-pds">'</span></span><span class="pl-k">:</span> <span
                class="pl-s"><span class="pl-pds">'</span>c<span class="pl-pds">'</span></span>,
  length<span class="pl-k">:</span> <span class="pl-c1">3</span>
};

<span class="pl-c"><span class="pl-c">//</span> TypeError: Cannot spread non-iterable object.</span>
<span class="pl-k">let</span> arr <span class="pl-k">=</span> [<span class="pl-k">...</span>arrayLike];</pre>
    </div>
    <p>上面代码中，<code>arrayLike</code>是一个类似数组的对象，但是没有部署 Iterator 接口，扩展运算符就会报错。这时，可以改为使用<code>Array.from</code>方法将<code>arrayLike</code>转为真正的数组。
    </p>
    <p><strong>（6）Map 和 Set 结构，Generator 函数</strong></p>
    <p>扩展运算符内部调用的是数据结构的 Iterator 接口，因此只要具有 Iterator 接口的对象，都可以使用扩展运算符，比如 Map 结构。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> map <span class="pl-k">=</span> <span
            class="pl-k">new</span> <span class="pl-en">Map</span>([
  [<span class="pl-c1">1</span>, <span class="pl-s"><span class="pl-pds">'</span>one<span class="pl-pds">'</span></span>],
  [<span class="pl-c1">2</span>, <span class="pl-s"><span class="pl-pds">'</span>two<span class="pl-pds">'</span></span>],
  [<span class="pl-c1">3</span>, <span class="pl-s"><span class="pl-pds">'</span>three<span
                class="pl-pds">'</span></span>],
]);

<span class="pl-k">let</span> arr <span class="pl-k">=</span> [<span class="pl-k">...</span><span
                class="pl-smi">map</span>.<span class="pl-c1">keys</span>()]; <span class="pl-c"><span
                class="pl-c">//</span> [1, 2, 3]</span></pre>
    </div>
    <p>Generator 函数运行后，返回一个遍历器对象，因此也可以使用扩展运算符。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">go</span> <span
            class="pl-k">=</span> <span class="pl-k">function</span><span class="pl-k">*</span>(){
  <span class="pl-k">yield</span> <span class="pl-c1">1</span>;
  <span class="pl-k">yield</span> <span class="pl-c1">2</span>;
  <span class="pl-k">yield</span> <span class="pl-c1">3</span>;
};

[<span class="pl-k">...</span><span class="pl-en">go</span>()] <span class="pl-c"><span class="pl-c">//</span> [1, 2, 3]</span></pre>
    </div>
    <p>上面代码中，变量<code>go</code>是一个 Generator 函数，执行后返回的是一个遍历器对象，对这个遍历器对象执行扩展运算符，就会将内部遍历得到的值，转为一个数组。</p>
    <p>如果对没有 Iterator 接口的对象，使用扩展运算符，将会报错。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">obj</span> <span
            class="pl-k">=</span> {a<span class="pl-k">:</span> <span class="pl-c1">1</span>, b<span
            class="pl-k">:</span> <span class="pl-c1">2</span>};
<span class="pl-k">let</span> arr <span class="pl-k">=</span> [<span class="pl-k">...</span>obj]; <span
                class="pl-c"><span class="pl-c">//</span> TypeError: Cannot spread non-iterable object</span></pre>
    </div>
    <h2><a href="#arrayfrom"  class="anchor" id="user-content-arrayfrom">

    </a>Array.from()
    </h2>
    <p><code>Array.from</code>方法用于将两类对象转为真正的数组：类似数组的对象（array-like object）和可遍历（iterable）的对象（包括 ES6 新增的数据结构 Set 和 Map）。
    </p>
    <p>下面是一个类似数组的对象，<code>Array.from</code>将它转为真正的数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> arrayLike <span class="pl-k">=</span> {
    <span class="pl-s"><span class="pl-pds">'</span>0<span class="pl-pds">'</span></span><span
                class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>a<span
                class="pl-pds">'</span></span>,
    <span class="pl-s"><span class="pl-pds">'</span>1<span class="pl-pds">'</span></span><span
                class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>b<span
                class="pl-pds">'</span></span>,
    <span class="pl-s"><span class="pl-pds">'</span>2<span class="pl-pds">'</span></span><span
                class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>c<span
                class="pl-pds">'</span></span>,
    length<span class="pl-k">:</span> <span class="pl-c1">3</span>
};

<span class="pl-c"><span class="pl-c">//</span> ES5的写法</span>
<span class="pl-k">var</span> arr1 <span class="pl-k">=</span> [].<span class="pl-smi">slice</span>.<span class="pl-c1">call</span>(arrayLike); <span
                class="pl-c"><span class="pl-c">//</span> ['a', 'b', 'c']</span>

<span class="pl-c"><span class="pl-c">//</span> ES6的写法</span>
<span class="pl-k">let</span> arr2 <span class="pl-k">=</span> <span class="pl-c1">Array</span>.<span
                class="pl-en">from</span>(arrayLike); <span class="pl-c"><span
                class="pl-c">//</span> ['a', 'b', 'c']</span></pre>
    </div>
    <p>实际应用中，常见的类似数组的对象是 DOM 操作返回的 NodeList 集合，以及函数内部的<code>arguments</code>对象。<code>Array.from</code>都可以将它们转为真正的数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> NodeList对象</span>
<span class="pl-k">let</span> ps <span class="pl-k">=</span> <span class="pl-c1">document</span>.<span class="pl-c1">querySelectorAll</span>(<span
                class="pl-s"><span class="pl-pds">'</span>p<span class="pl-pds">'</span></span>);
<span class="pl-c1">Array</span>.<span class="pl-en">from</span>(ps).<span class="pl-c1">forEach</span>(<span
                class="pl-k">function</span> (<span class="pl-smi">p</span>) {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(p);
});

<span class="pl-c"><span class="pl-c">//</span> arguments对象</span>
<span class="pl-k">function</span> <span class="pl-en">foo</span>() {
  <span class="pl-k">var</span> args <span class="pl-k">=</span> <span class="pl-c1">Array</span>.<span class="pl-en">from</span>(<span
                class="pl-c1">arguments</span>);
  <span class="pl-c"><span class="pl-c">//</span> ...</span>
}</pre>
    </div>
    <p>上面代码中，<code>querySelectorAll</code>方法返回的是一个类似数组的对象，可以将这个对象转为真正的数组，再使用<code>forEach</code>方法。</p>
    <p>只要是部署了 Iterator 接口的数据结构，<code>Array.from</code>都能将其转为数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c1">Array</span>.<span
            class="pl-en">from</span>(<span class="pl-s"><span class="pl-pds">'</span>hello<span class="pl-pds">'</span></span>)
<span class="pl-c"><span class="pl-c">//</span> ['h', 'e', 'l', 'l', 'o']</span>

<span class="pl-k">let</span> namesSet <span class="pl-k">=</span> <span class="pl-k">new</span> <span
                class="pl-en">Set</span>([<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>, <span
                class="pl-s"><span class="pl-pds">'</span>b<span class="pl-pds">'</span></span>])
<span class="pl-c1">Array</span>.<span class="pl-en">from</span>(namesSet) <span class="pl-c"><span
                class="pl-c">//</span> ['a', 'b']</span></pre>
    </div>
    <p>上面代码中，字符串和 Set 结构都具有 Iterator 接口，因此可以被<code>Array.from</code>转为真正的数组。</p>
    <p>如果参数是一个真正的数组，<code>Array.from</code>会返回一个一模一样的新数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c1">Array</span>.<span
            class="pl-en">from</span>([<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span
            class="pl-c1">3</span>])
<span class="pl-c"><span class="pl-c">//</span> [1, 2, 3]</span></pre>
    </div>
    <p>值得提醒的是，扩展运算符（<code>...</code>）也可以将某些数据结构转为数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> arguments对象</span>
<span class="pl-k">function</span> <span class="pl-en">foo</span>() {
  <span class="pl-k">const</span> <span class="pl-c1">args</span> <span class="pl-k">=</span> [<span
                class="pl-k">...</span><span class="pl-c1">arguments</span>];
}

<span class="pl-c"><span class="pl-c">//</span> NodeList对象</span>
[<span class="pl-k">...</span><span class="pl-c1">document</span>.<span class="pl-c1">querySelectorAll</span>(<span
                class="pl-s"><span class="pl-pds">'</span>div<span class="pl-pds">'</span></span>)]</pre>
    </div>
    <p>扩展运算符背后调用的是遍历器接口（<code>Symbol.iterator</code>），如果一个对象没有部署这个接口，就无法转换。<code>Array.from</code>方法还支持类似数组的对象。所谓类似数组的对象，本质特征只有一点，即必须有<code>length</code>属性。因此，任何有<code>length</code>属性的对象，都可以通过<code>Array.from</code>方法转为数组，而此时扩展运算符就无法转换。
    </p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c1">Array</span>.<span class="pl-en">from</span>({ length<span
            class="pl-k">:</span> <span class="pl-c1">3</span> });
<span class="pl-c"><span class="pl-c">//</span> [ undefined, undefined, undefined ]</span></pre>
    </div>
    <p>上面代码中，<code>Array.from</code>返回了一个具有三个成员的数组，每个位置的值都是<code>undefined</code>。扩展运算符转换不了这个对象。</p>
    <p>对于还没有部署该方法的浏览器，可以用<code>Array.prototype.slice</code>方法替代。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span
            class="pl-c1">toArray</span> <span class="pl-k">=</span> (() <span class="pl-k">=&gt;</span>
  <span class="pl-c1">Array</span>.<span class="pl-smi">from</span> <span class="pl-k">?</span> <span class="pl-c1">Array</span>.<span
                class="pl-smi">from</span> <span class="pl-k">:</span> <span class="pl-smi">obj</span> <span
                class="pl-k">=&gt;</span> [].<span class="pl-smi">slice</span>.<span class="pl-c1">call</span>(obj)
)();</pre>
    </div>
    <p><code>Array.from</code>还可以接受第二个参数，作用类似于数组的<code>map</code>方法，用来对每个元素进行处理，将处理后的值放入返回的数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c1">Array</span>.<span class="pl-en">from</span>(arrayLike, <span
            class="pl-smi">x</span> <span class="pl-k">=&gt;</span> x <span class="pl-k">*</span> x);
<span class="pl-c"><span class="pl-c">//</span> 等同于</span>
<span class="pl-c1">Array</span>.<span class="pl-en">from</span>(arrayLike).<span class="pl-en">map</span>(<span
                class="pl-smi">x</span> <span class="pl-k">=&gt;</span> x <span class="pl-k">*</span> x);

<span class="pl-c1">Array</span>.<span class="pl-en">from</span>([<span class="pl-c1">1</span>, <span
                class="pl-c1">2</span>, <span class="pl-c1">3</span>], (<span class="pl-smi">x</span>) <span
                class="pl-k">=&gt;</span> x <span class="pl-k">*</span> x)
<span class="pl-c"><span class="pl-c">//</span> [1, 4, 9]</span></pre>
    </div>
    <p>下面的例子是取出一组 DOM 节点的文本内容。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> spans <span
            class="pl-k">=</span> <span class="pl-c1">document</span>.<span class="pl-c1">querySelectorAll</span>(<span
            class="pl-s"><span class="pl-pds">'</span>span.name<span class="pl-pds">'</span></span>);

<span class="pl-c"><span class="pl-c">//</span> map()</span>
<span class="pl-k">let</span> names1 <span class="pl-k">=</span> <span class="pl-c1">Array</span>.<span class="pl-c1">prototype</span>.<span
                class="pl-smi">map</span>.<span class="pl-c1">call</span>(spans, <span class="pl-smi">s</span> <span
                class="pl-k">=&gt;</span> <span class="pl-smi">s</span>.<span class="pl-smi">textContent</span>);

<span class="pl-c"><span class="pl-c">//</span> Array.from()</span>
<span class="pl-k">let</span> names2 <span class="pl-k">=</span> <span class="pl-c1">Array</span>.<span class="pl-en">from</span>(spans, <span
                class="pl-smi">s</span> <span class="pl-k">=&gt;</span> <span class="pl-smi">s</span>.<span
                class="pl-smi">textContent</span>)</pre>
    </div>
    <p>下面的例子将数组中布尔值为<code>false</code>的成员转为<code>0</code>。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c1">Array</span>.<span
            class="pl-en">from</span>([<span class="pl-c1">1</span>, , <span class="pl-c1">2</span>, , <span
            class="pl-c1">3</span>], (<span class="pl-smi">n</span>) <span class="pl-k">=&gt;</span> n <span
            class="pl-k">||</span> <span class="pl-c1">0</span>)
<span class="pl-c"><span class="pl-c">//</span> [1, 0, 2, 0, 3]</span></pre>
    </div>
    <p>另一个例子是返回各种数据的类型。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span
            class="pl-en">typesOf</span> () {
  <span class="pl-k">return</span> <span class="pl-c1">Array</span>.<span class="pl-en">from</span>(<span class="pl-c1">arguments</span>, <span
                class="pl-smi">value</span> <span class="pl-k">=&gt;</span> <span class="pl-k">typeof</span> value)
}
<span class="pl-en">typesOf</span>(<span class="pl-c1">null</span>, [], <span class="pl-c1">NaN</span>)
<span class="pl-c"><span class="pl-c">//</span> ['object', 'object', 'number']</span></pre>
    </div>
    <p>如果<code>map</code>函数里面用到了<code>this</code>关键字，还可以传入<code>Array.from</code>的第三个参数，用来绑定<code>this</code>。</p>
    <p><code>Array.from()</code>可以将各种值转为真正的数组，并且还提供<code>map</code>功能。这实际上意味着，只要有一个原始的数据结构，你就可以先对它的值进行处理，然后转成规范的数组结构，进而就可以使用数量众多的数组方法。
    </p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c1">Array</span>.<span class="pl-en">from</span>({ length<span
            class="pl-k">:</span> <span class="pl-c1">2</span> }, () <span class="pl-k">=&gt;</span> <span class="pl-s"><span
            class="pl-pds">'</span>jack<span class="pl-pds">'</span></span>)
<span class="pl-c"><span class="pl-c">//</span> ['jack', 'jack']</span></pre>
    </div>
    <p>上面代码中，<code>Array.from</code>的第一个参数指定了第二个参数运行的次数。这种特性可以让该方法的用法变得非常灵活。</p>
    <p><code>Array.from()</code>的另一个应用是，将字符串转为数组，然后返回字符串的长度。因为它能正确处理各种 Unicode 字符，可以避免 JavaScript 将大于<code>\uFFFF</code>的
        Unicode 字符，算作两个字符的 bug。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span
            class="pl-en">countSymbols</span>(<span class="pl-smi">string</span>) {
  <span class="pl-k">return</span> <span class="pl-c1">Array</span>.<span class="pl-en">from</span>(string).<span
                class="pl-c1">length</span>;
}</pre>
    </div>
    <h2><a href="#arrayof"  class="anchor" id="user-content-arrayof">

    </a>Array.of()
    </h2>
    <p><code>Array.of</code>方法用于将一组值，转换为数组。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c1">Array</span>.<span class="pl-en">of</span>(<span
            class="pl-c1">3</span>, <span class="pl-c1">11</span>, <span class="pl-c1">8</span>) <span
            class="pl-c"><span class="pl-c">//</span> [3,11,8]</span>
<span class="pl-c1">Array</span>.<span class="pl-en">of</span>(<span class="pl-c1">3</span>) <span class="pl-c"><span
                class="pl-c">//</span> [3]</span>
<span class="pl-c1">Array</span>.<span class="pl-en">of</span>(<span class="pl-c1">3</span>).<span
                class="pl-c1">length</span> <span class="pl-c"><span class="pl-c">//</span> 1</span></pre>
    </div>
    <p>这个方法的主要目的，是弥补数组构造函数<code>Array()</code>的不足。因为参数个数的不同，会导致<code>Array()</code>的行为有差异。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c1">Array</span>() <span class="pl-c"><span
            class="pl-c">//</span> []</span>
<span class="pl-c1">Array</span>(<span class="pl-c1">3</span>) <span class="pl-c"><span
                class="pl-c">//</span> [, , ,]</span>
<span class="pl-c1">Array</span>(<span class="pl-c1">3</span>, <span class="pl-c1">11</span>, <span
                class="pl-c1">8</span>) <span class="pl-c"><span class="pl-c">//</span> [3, 11, 8]</span></pre>
    </div>
    <p>上面代码中，<code>Array</code>方法没有参数、一个参数、三个参数时，返回结果都不一样。只有当参数个数不少于 2 个时，<code>Array()</code>才会返回由参数组成的新数组。参数个数只有一个时，实际上是指定数组的长度。
    </p>
    <p><code>Array.of</code>基本上可以用来替代<code>Array()</code>或<code>new Array()</code>，并且不存在由于参数不同而导致的重载。它的行为非常统一。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c1">Array</span>.<span
            class="pl-en">of</span>() <span class="pl-c"><span class="pl-c">//</span> []</span>
<span class="pl-c1">Array</span>.<span class="pl-en">of</span>(<span class="pl-c1">undefined</span>) <span class="pl-c"><span
                class="pl-c">//</span> [undefined]</span>
<span class="pl-c1">Array</span>.<span class="pl-en">of</span>(<span class="pl-c1">1</span>) <span class="pl-c"><span
                class="pl-c">//</span> [1]</span>
<span class="pl-c1">Array</span>.<span class="pl-en">of</span>(<span class="pl-c1">1</span>, <span
                class="pl-c1">2</span>) <span class="pl-c"><span class="pl-c">//</span> [1, 2]</span></pre>
    </div>
    <p><code>Array.of</code>总是返回参数值组成的数组。如果没有参数，就返回一个空数组。</p>
    <p><code>Array.of</code>方法可以用下面的代码模拟实现。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span
            class="pl-en">ArrayOf</span>(){
  <span class="pl-k">return</span> [].<span class="pl-smi">slice</span>.<span class="pl-c1">call</span>(<span
                class="pl-c1">arguments</span>);
}</pre>
    </div>
    <h2><a href="#数组实例的-copywithin"  class="anchor" id="user-content-数组实例的-copywithin">

    </a>数组实例的 copyWithin()
    </h2>
    <p>数组实例的<code>copyWithin</code>方法，在当前数组内部，将指定位置的成员复制到其他位置（会覆盖原有成员），然后返回当前数组。也就是说，使用这个方法，会修改当前数组。</p>
    <div class="highlight highlight-source-js">
        <pre><span class="pl-c1">Array</span>.<span class="pl-c1">prototype</span>.<span class="pl-en">copyWithin</span>(target, start <span
                class="pl-k">=</span> <span class="pl-c1">0</span>, end <span class="pl-k">=</span> <span class="pl-c1">this</span>.<span
                class="pl-c1">length</span>)</pre>
    </div>
    <p>它接受三个参数。</p>
    <ul>
        <li>target（必需）：从该位置开始替换数据。</li>
        <li>start（可选）：从该位置开始读取数据，默认为 0。如果为负值，表示倒数。</li>
        <li>end（可选）：到该位置前停止读取数据，默认等于数组长度。如果为负值，表示倒数。</li>
    </ul>
    <p>这三个参数都应该是数值，如果不是，会自动转为数值。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span
            class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span class="pl-c1">5</span>].<span class="pl-en">copyWithin</span>(<span
            class="pl-c1">0</span>, <span class="pl-c1">3</span>)
<span class="pl-c"><span class="pl-c">//</span> [4, 5, 3, 4, 5]</span></pre>
    </div>
    <p>上面代码表示将从 3 号位直到数组结束的成员（4 和 5），复制到从 0 号位开始的位置，结果覆盖了原来的 1 和 2。</p>
    <p>下面是更多例子。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 将3号位复制到0号位</span>
[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span
                class="pl-c1">5</span>].<span class="pl-en">copyWithin</span>(<span class="pl-c1">0</span>, <span
                class="pl-c1">3</span>, <span class="pl-c1">4</span>)
<span class="pl-c"><span class="pl-c">//</span> [4, 2, 3, 4, 5]</span>

<span class="pl-c"><span class="pl-c">//</span> -2相当于3号位，-1相当于4号位</span>
[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span
                class="pl-c1">5</span>].<span class="pl-en">copyWithin</span>(<span class="pl-c1">0</span>, <span
                class="pl-k">-</span><span class="pl-c1">2</span>, <span class="pl-k">-</span><span
                class="pl-c1">1</span>)
<span class="pl-c"><span class="pl-c">//</span> [4, 2, 3, 4, 5]</span>

<span class="pl-c"><span class="pl-c">//</span> 将3号位复制到0号位</span>
[].<span class="pl-smi">copyWithin</span>.<span class="pl-c1">call</span>({length<span class="pl-k">:</span> <span
                class="pl-c1">5</span>, <span class="pl-c1">3</span><span class="pl-k">:</span> <span
                class="pl-c1">1</span>}, <span class="pl-c1">0</span>, <span class="pl-c1">3</span>)
<span class="pl-c"><span class="pl-c">//</span> {0: 1, 3: 1, length: 5}</span>

<span class="pl-c"><span class="pl-c">//</span> 将2号位到数组结束，复制到0号位</span>
<span class="pl-k">let</span> i32a <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">Int32Array</span>([<span
                class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span
                class="pl-c1">5</span>]);
<span class="pl-smi">i32a</span>.<span class="pl-en">copyWithin</span>(<span class="pl-c1">0</span>, <span
                class="pl-c1">2</span>);
<span class="pl-c"><span class="pl-c">//</span> Int32Array [3, 4, 5, 4, 5]</span>

<span class="pl-c"><span class="pl-c">//</span> 对于没有部署 TypedArray 的 copyWithin 方法的平台</span>
<span class="pl-c"><span class="pl-c">//</span> 需要采用下面的写法</span>
[].<span class="pl-smi">copyWithin</span>.<span class="pl-c1">call</span>(<span class="pl-k">new</span> <span
                class="pl-en">Int32Array</span>([<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span
                class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span class="pl-c1">5</span>]), <span
                class="pl-c1">0</span>, <span class="pl-c1">3</span>, <span class="pl-c1">4</span>);
<span class="pl-c"><span class="pl-c">//</span> Int32Array [4, 2, 3, 4, 5]</span></pre>
    </div>
    <h2><a href="#数组实例的-find-和-findindex"  class="anchor" id="user-content-数组实例的-find-和-findindex">

    </a>数组实例的 find() 和 findIndex()
    </h2>
    <p>数组实例的<code>find</code>方法，用于找出第一个符合条件的数组成员。它的参数是一个回调函数，所有数组成员依次执行该回调函数，直到找出第一个返回值为<code>true</code>的成员，然后返回该成员。如果没有符合条件的成员，则返回<code>undefined</code>。
    </p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-c1">1</span>, <span class="pl-c1">4</span>, <span
            class="pl-k">-</span><span class="pl-c1">5</span>, <span class="pl-c1">10</span>].<span
            class="pl-c1">find</span>((<span class="pl-smi">n</span>) <span class="pl-k">=&gt;</span> n <span
            class="pl-k">&lt;</span> <span class="pl-c1">0</span>)
<span class="pl-c"><span class="pl-c">//</span> -5</span></pre>
    </div>
    <p>上面代码找出数组中第一个小于 0 的成员。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-c1">1</span>, <span class="pl-c1">5</span>, <span
            class="pl-c1">10</span>, <span class="pl-c1">15</span>].<span class="pl-c1">find</span>(<span class="pl-k">function</span>(<span
            class="pl-smi">value</span>, <span class="pl-smi">index</span>, <span class="pl-smi">arr</span>) {
  <span class="pl-k">return</span> value <span class="pl-k">&gt;</span> <span class="pl-c1">9</span>;
}) <span class="pl-c"><span class="pl-c">//</span> 10</span></pre>
    </div>
    <p>上面代码中，<code>find</code>方法的回调函数可以接受三个参数，依次为当前的值、当前的位置和原数组。</p>
    <p>数组实例的<code>findIndex</code>方法的用法与<code>find</code>方法非常类似，返回第一个符合条件的数组成员的位置，如果所有成员都不符合条件，则返回<code>-1</code>。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-c1">1</span>, <span class="pl-c1">5</span>, <span
            class="pl-c1">10</span>, <span class="pl-c1">15</span>].<span class="pl-en">findIndex</span>(<span
            class="pl-k">function</span>(<span class="pl-smi">value</span>, <span class="pl-smi">index</span>, <span
            class="pl-smi">arr</span>) {
  <span class="pl-k">return</span> value <span class="pl-k">&gt;</span> <span class="pl-c1">9</span>;
}) <span class="pl-c"><span class="pl-c">//</span> 2</span></pre>
    </div>
    <p>这两个方法都可以接受第二个参数，用来绑定回调函数的<code>this</code>对象。</p>
    <p>另外，这两个方法都可以发现<code>NaN</code>，弥补了数组的<code>indexOf</code>方法的不足。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-c1">NaN</span>].<span class="pl-c1">indexOf</span>(<span
            class="pl-c1">NaN</span>)
<span class="pl-c"><span class="pl-c">//</span> -1</span>

[<span class="pl-c1">NaN</span>].<span class="pl-en">findIndex</span>(<span class="pl-smi">y</span> <span class="pl-k">=&gt;</span> <span
                class="pl-c1">Object</span>.<span class="pl-en">is</span>(<span class="pl-c1">NaN</span>, y))
<span class="pl-c"><span class="pl-c">//</span> 0</span></pre>
    </div>
    <p>上面代码中，<code>indexOf</code>方法无法识别数组的<code>NaN</code>成员，但是<code>findIndex</code>方法可以借助<code>Object.is</code>方法做到。
    </p>
    <h2><a href="#数组实例的-fill"  class="anchor" id="user-content-数组实例的-fill">

    </a>数组实例的 fill()
    </h2>
    <p><code>fill</code>方法使用给定值，填充一个数组。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-s"><span class="pl-pds">'</span>a<span
            class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>b<span
            class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>c<span
            class="pl-pds">'</span></span>].<span class="pl-en">fill</span>(<span class="pl-c1">7</span>)
<span class="pl-c"><span class="pl-c">//</span> [7, 7, 7]</span>

<span class="pl-k">new</span> <span class="pl-en">Array</span>(<span class="pl-c1">3</span>).<span
                class="pl-en">fill</span>(<span class="pl-c1">7</span>)
<span class="pl-c"><span class="pl-c">//</span> [7, 7, 7]</span></pre>
    </div>
    <p>上面代码表明，<code>fill</code>方法用于空数组的初始化非常方便。数组中已有的元素，会被全部抹去。</p>
    <p><code>fill</code>方法还可以接受第二个和第三个参数，用于指定填充的起始位置和结束位置。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-s"><span class="pl-pds">'</span>a<span
            class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>b<span
            class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>c<span
            class="pl-pds">'</span></span>].<span class="pl-en">fill</span>(<span class="pl-c1">7</span>, <span
            class="pl-c1">1</span>, <span class="pl-c1">2</span>)
<span class="pl-c"><span class="pl-c">//</span> ['a', 7, 'c']</span></pre>
    </div>
    <p>上面代码表示，<code>fill</code>方法从 1 号位开始，向原数组填充 7，到 2 号位之前结束。</p>
    <h2><a href="#数组实例的-entrieskeys-和-values"  class="anchor"
           id="user-content-数组实例的-entrieskeys-和-values">

    </a>数组实例的 entries()，keys() 和 values()
    </h2>
    <p>ES6 提供三个新的方法——<code>entries()</code>，<code>keys()</code>和<code>values()</code>——用于遍历数组。它们都返回一个遍历器对象（详见《Iterator》一章），可以用<code>for...of</code>循环进行遍历，唯一的区别是<code>keys()</code>是对键名的遍历、<code>values()</code>是对键值的遍历，<code>entries()</code>是对键值对的遍历。
    </p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">for</span> (<span
            class="pl-k">let</span> index <span class="pl-k">of</span> [<span class="pl-s"><span class="pl-pds">'</span>a<span
            class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>b<span
            class="pl-pds">'</span></span>].<span class="pl-c1">keys</span>()) {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(index);
}
<span class="pl-c"><span class="pl-c">//</span> 0</span>
<span class="pl-c"><span class="pl-c">//</span> 1</span>

<span class="pl-k">for</span> (<span class="pl-k">let</span> elem <span class="pl-k">of</span> [<span class="pl-s"><span
                class="pl-pds">'</span>a<span class="pl-pds">'</span></span>, <span class="pl-s"><span
                class="pl-pds">'</span>b<span class="pl-pds">'</span></span>].<span class="pl-c1">values</span>()) {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(elem);
}
<span class="pl-c"><span class="pl-c">//</span> 'a'</span>
<span class="pl-c"><span class="pl-c">//</span> 'b'</span>

<span class="pl-k">for</span> (<span class="pl-k">let</span> [index, elem] <span class="pl-k">of</span> [<span
                class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>, <span
                class="pl-s"><span class="pl-pds">'</span>b<span class="pl-pds">'</span></span>].<span class="pl-c1">entries</span>()) {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(index, elem);
}
<span class="pl-c"><span class="pl-c">//</span> 0 "a"</span>
<span class="pl-c"><span class="pl-c">//</span> 1 "b"</span></pre>
    </div>
    <p>如果不使用<code>for...of</code>循环，可以手动调用遍历器对象的<code>next</code>方法，进行遍历。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> letter <span
            class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>, <span
            class="pl-s"><span class="pl-pds">'</span>b<span class="pl-pds">'</span></span>, <span class="pl-s"><span
            class="pl-pds">'</span>c<span class="pl-pds">'</span></span>];
<span class="pl-k">let</span> entries <span class="pl-k">=</span> <span class="pl-smi">letter</span>.<span
                class="pl-c1">entries</span>();
<span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-smi">entries</span>.<span
                class="pl-c1">next</span>().<span class="pl-c1">value</span>); <span class="pl-c"><span
                class="pl-c">//</span> [0, 'a']</span>
<span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-smi">entries</span>.<span
                class="pl-c1">next</span>().<span class="pl-c1">value</span>); <span class="pl-c"><span
                class="pl-c">//</span> [1, 'b']</span>
<span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-smi">entries</span>.<span
                class="pl-c1">next</span>().<span class="pl-c1">value</span>); <span class="pl-c"><span
                class="pl-c">//</span> [2, 'c']</span></pre>
    </div>
    <h2><a href="#数组实例的-includes"  class="anchor" id="user-content-数组实例的-includes">

    </a>数组实例的 includes()
    </h2>
    <p><code>Array.prototype.includes</code>方法返回一个布尔值，表示某个数组是否包含给定的值，与字符串的<code>includes</code>方法类似。ES2016 引入了该方法。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span
            class="pl-c1">3</span>].<span class="pl-en">includes</span>(<span class="pl-c1">2</span>)     <span
            class="pl-c"><span class="pl-c">//</span> true</span>
[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>].<span
                class="pl-en">includes</span>(<span class="pl-c1">4</span>)     <span class="pl-c"><span
                class="pl-c">//</span> false</span>
[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">NaN</span>].<span class="pl-en">includes</span>(<span
                class="pl-c1">NaN</span>) <span class="pl-c"><span class="pl-c">//</span> true</span></pre>
    </div>
    <p>该方法的第二个参数表示搜索的起始位置，默认为<code>0</code>。如果第二个参数为负数，则表示倒数的位置，如果这时它大于数组长度（比如第二个参数为<code>-4</code>，但数组长度为<code>3</code>），则会重置为从<code>0</code>开始。
    </p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span
            class="pl-c1">3</span>].<span class="pl-en">includes</span>(<span class="pl-c1">3</span>, <span
            class="pl-c1">3</span>);  <span class="pl-c"><span class="pl-c">//</span> false</span>
[<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>].<span
                class="pl-en">includes</span>(<span class="pl-c1">3</span>, <span class="pl-k">-</span><span
                class="pl-c1">1</span>); <span class="pl-c"><span class="pl-c">//</span> true</span></pre>
    </div>
    <p>没有该方法之前，我们通常使用数组的<code>indexOf</code>方法，检查是否包含某个值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">if</span> (<span class="pl-smi">arr</span>.<span
            class="pl-c1">indexOf</span>(el) <span class="pl-k">!==</span> <span class="pl-k">-</span><span
            class="pl-c1">1</span>) {
  <span class="pl-c"><span class="pl-c">//</span> ...</span>
}</pre>
    </div>
    <p><code>indexOf</code>方法有两个缺点，一是不够语义化，它的含义是找到参数值的第一个出现位置，所以要去比较是否不等于<code>-1</code>，表达起来不够直观。二是，它内部使用严格相等运算符（<code>===</code>）进行判断，这会导致对<code>NaN</code>的误判。
    </p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-c1">NaN</span>].<span class="pl-c1">indexOf</span>(<span
            class="pl-c1">NaN</span>)
<span class="pl-c"><span class="pl-c">//</span> -1</span></pre>
    </div>
    <p><code>includes</code>使用的是不一样的判断算法，就没有这个问题。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-c1">NaN</span>].<span class="pl-en">includes</span>(<span
            class="pl-c1">NaN</span>)
<span class="pl-c"><span class="pl-c">//</span> true</span></pre>
    </div>
    <p>下面代码用来检查当前环境是否支持该方法，如果不支持，部署一个简易的替代版本。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">contains</span> <span
            class="pl-k">=</span> (() <span class="pl-k">=&gt;</span>
  <span class="pl-c1">Array</span>.<span class="pl-c1">prototype</span>.<span class="pl-smi">includes</span>
    <span class="pl-k">?</span> (<span class="pl-smi">arr</span>, <span class="pl-smi">value</span>) <span class="pl-k">=&gt;</span> <span
                class="pl-smi">arr</span>.<span class="pl-en">includes</span>(value)
    <span class="pl-k">:</span> (<span class="pl-smi">arr</span>, <span class="pl-smi">value</span>) <span class="pl-k">=&gt;</span> <span
                class="pl-smi">arr</span>.<span class="pl-en">some</span>(<span class="pl-smi">el</span> <span
                class="pl-k">=&gt;</span> el <span class="pl-k">===</span> value)
)();
<span class="pl-en">contains</span>([<span class="pl-s"><span class="pl-pds">'</span>foo<span
                class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>bar<span class="pl-pds">'</span></span>], <span
                class="pl-s"><span class="pl-pds">'</span>baz<span class="pl-pds">'</span></span>); <span
                class="pl-c"><span class="pl-c">//</span> =&gt; false</span></pre>
    </div>
    <p>另外，Map 和 Set 数据结构有一个<code>has</code>方法，需要注意与<code>includes</code>区分。</p>
    <ul>
        <li>Map
            结构的<code>has</code>方法，是用来查找键名的，比如<code>Map.prototype.has(key)</code>、<code>WeakMap.prototype.has(key)</code>、<code>Reflect.has(target,
                propertyKey)</code>。
        </li>
        <li>Set
            结构的<code>has</code>方法，是用来查找值的，比如<code>Set.prototype.has(value)</code>、<code>WeakSet.prototype.has(value)</code>。
        </li>
    </ul>
    <h2><a href="#数组的空位"  class="anchor" id="user-content-数组的空位">

    </a>数组的空位
    </h2>
    <p>数组的空位指，数组的某一个位置没有任何值。比如，<code>Array</code>构造函数返回的数组都是空位。</p>
    <div class="highlight highlight-source-js">
        <pre><span class="pl-c1">Array</span>(<span class="pl-c1">3</span>) <span class="pl-c"><span
                class="pl-c">//</span> [, , ,]</span></pre>
    </div>
    <p>上面代码中，<code>Array(3)</code>返回一个具有 3 个空位的数组。</p>
    <p>注意，空位不是<code>undefined</code>，一个位置的值等于<code>undefined</code>，依然是有值的。空位是没有任何值，<code>in</code>运算符可以说明这一点。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c1">0</span> <span class="pl-k">in</span> [<span
            class="pl-c1">undefined</span>, <span class="pl-c1">undefined</span>, <span class="pl-c1">undefined</span>] <span
            class="pl-c"><span class="pl-c">//</span> true</span>
<span class="pl-c1">0</span> <span class="pl-k">in</span> [, , ,] <span class="pl-c"><span class="pl-c">//</span> false</span></pre>
    </div>
    <p>上面代码说明，第一个数组的 0 号位置是有值的，第二个数组的 0 号位置没有值。</p>
    <p>ES5 对空位的处理，已经很不一致了，大多数情况下会忽略空位。</p>
    <ul>
        <li><code>forEach()</code>, <code>filter()</code>, <code>every()</code> 和<code>some()</code>都会跳过空位。</li>
        <li><code>map()</code>会跳过空位，但会保留这个值</li>
        <li>
            <code>join()</code>和<code>toString()</code>会将空位视为<code>undefined</code>，而<code>undefined</code>和<code>null</code>会被处理成空字符串。
        </li>
    </ul>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> forEach方法</span>
[,<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>].<span
                class="pl-c1">forEach</span>((<span class="pl-smi">x</span>,<span class="pl-smi">i</span>) <span
                class="pl-k">=&gt;</span> <span class="pl-en">console</span>.<span class="pl-c1">log</span>(i)); <span
                class="pl-c"><span class="pl-c">//</span> 1</span>

<span class="pl-c"><span class="pl-c">//</span> filter方法</span>
[<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>,,<span class="pl-s"><span
                class="pl-pds">'</span>b<span class="pl-pds">'</span></span>].<span class="pl-en">filter</span>(<span
                class="pl-smi">x</span> <span class="pl-k">=&gt;</span> <span class="pl-c1">true</span>) <span
                class="pl-c"><span class="pl-c">//</span> ['a','b']</span>

<span class="pl-c"><span class="pl-c">//</span> every方法</span>
[,<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>].<span
                class="pl-en">every</span>(<span class="pl-smi">x</span> <span class="pl-k">=&gt;</span> x<span
                class="pl-k">===</span><span class="pl-s"><span class="pl-pds">'</span>a<span
                class="pl-pds">'</span></span>) <span class="pl-c"><span class="pl-c">//</span> true</span>

<span class="pl-c"><span class="pl-c">//</span> some方法</span>
[,<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>].<span class="pl-en">some</span>(<span
                class="pl-smi">x</span> <span class="pl-k">=&gt;</span> x <span class="pl-k">!==</span> <span
                class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>) <span
                class="pl-c"><span class="pl-c">//</span> false</span>

<span class="pl-c"><span class="pl-c">//</span> map方法</span>
[,<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>].<span class="pl-en">map</span>(<span
                class="pl-smi">x</span> <span class="pl-k">=&gt;</span> <span class="pl-c1">1</span>) <span
                class="pl-c"><span class="pl-c">//</span> [,1]</span>

<span class="pl-c"><span class="pl-c">//</span> join方法</span>
[,<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>,<span
                class="pl-c1">undefined</span>,<span class="pl-c1">null</span>].<span class="pl-c1">join</span>(<span
                class="pl-s"><span class="pl-pds">'</span>#<span class="pl-pds">'</span></span>) <span
                class="pl-c"><span class="pl-c">//</span> "#a##"</span>

<span class="pl-c"><span class="pl-c">//</span> toString方法</span>
[,<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>,<span
                class="pl-c1">undefined</span>,<span class="pl-c1">null</span>].<span
                class="pl-c1">toString</span>() <span class="pl-c"><span class="pl-c">//</span> ",a,,"</span></pre>
    </div>
    <p>ES6 则是明确将空位转为<code>undefined</code>。</p>
    <p><code>Array.from</code>方法会将数组的空位，转为<code>undefined</code>，也就是说，这个方法不会忽略空位。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c1">Array</span>.<span
            class="pl-en">from</span>([<span class="pl-s"><span class="pl-pds">'</span>a<span
            class="pl-pds">'</span></span>,,<span class="pl-s"><span class="pl-pds">'</span>b<span
            class="pl-pds">'</span></span>])
<span class="pl-c"><span class="pl-c">//</span> [ "a", undefined, "b" ]</span></pre>
    </div>
    <p>扩展运算符（<code>...</code>）也会将空位转为<code>undefined</code>。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-k">...</span>[<span class="pl-s"><span
            class="pl-pds">'</span>a<span class="pl-pds">'</span></span>,,<span class="pl-s"><span
            class="pl-pds">'</span>b<span class="pl-pds">'</span></span>]]
<span class="pl-c"><span class="pl-c">//</span> [ "a", undefined, "b" ]</span></pre>
    </div>
    <p><code>copyWithin()</code>会连空位一起拷贝。</p>
    <div class="highlight highlight-source-js">
        <pre>[,<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>,<span class="pl-s"><span
                class="pl-pds">'</span>b<span class="pl-pds">'</span></span>,,].<span
                class="pl-en">copyWithin</span>(<span class="pl-c1">2</span>,<span class="pl-c1">0</span>) <span
                class="pl-c"><span class="pl-c">//</span> [,"a",,"a"]</span></pre>
    </div>
    <p><code>fill()</code>会将空位视为正常的数组位置。</p>
    <div class="highlight highlight-source-js">
        <pre><span class="pl-k">new</span> <span class="pl-en">Array</span>(<span class="pl-c1">3</span>).<span
                class="pl-en">fill</span>(<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>) <span
                class="pl-c"><span class="pl-c">//</span> ["a","a","a"]</span></pre>
    </div>
    <p><code>for...of</code>循环也会遍历空位。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> arr <span class="pl-k">=</span> [, ,];
<span class="pl-k">for</span> (<span class="pl-k">let</span> i <span class="pl-k">of</span> arr) {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-c1">1</span>);
}
<span class="pl-c"><span class="pl-c">//</span> 1</span>
<span class="pl-c"><span class="pl-c">//</span> 1</span></pre>
    </div>
    <p>上面代码中，数组<code>arr</code>有两个空位，<code>for...of</code>并没有忽略它们。如果改成<code>map</code>方法遍历，空位是会跳过的。</p>
    <p><code>entries()</code>、<code>keys()</code>、<code>values()</code>、<code>find()</code>和<code>findIndex()</code>会将空位处理成<code>undefined</code>。
    </p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> entries()</span>
[<span class="pl-k">...</span>[,<span class="pl-s"><span class="pl-pds">'</span>a<span
                class="pl-pds">'</span></span>].<span class="pl-c1">entries</span>()] <span class="pl-c"><span
                class="pl-c">//</span> [[0,undefined], [1,"a"]]</span>

<span class="pl-c"><span class="pl-c">//</span> keys()</span>
[<span class="pl-k">...</span>[,<span class="pl-s"><span class="pl-pds">'</span>a<span
                class="pl-pds">'</span></span>].<span class="pl-c1">keys</span>()] <span class="pl-c"><span
                class="pl-c">//</span> [0,1]</span>

<span class="pl-c"><span class="pl-c">//</span> values()</span>
[<span class="pl-k">...</span>[,<span class="pl-s"><span class="pl-pds">'</span>a<span
                class="pl-pds">'</span></span>].<span class="pl-c1">values</span>()] <span class="pl-c"><span
                class="pl-c">//</span> [undefined,"a"]</span>

<span class="pl-c"><span class="pl-c">//</span> find()</span>
[,<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>].<span class="pl-c1">find</span>(<span
                class="pl-smi">x</span> <span class="pl-k">=&gt;</span> <span class="pl-c1">true</span>) <span
                class="pl-c"><span class="pl-c">//</span> undefined</span>

<span class="pl-c"><span class="pl-c">//</span> findIndex()</span>
[,<span class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>].<span
                class="pl-en">findIndex</span>(<span class="pl-smi">x</span> <span class="pl-k">=&gt;</span> <span
                class="pl-c1">true</span>) <span class="pl-c"><span class="pl-c">//</span> 0</span></pre>
    </div>
    <p>由于空位的处理规则非常不统一，所以建议避免出现空位。</p>
</div>
</body>
</html>
